package cn.dkdoo.blackhorse_transactional.common.dkdassert;

import cn.dkdoo.blackhorse_transactional.common.TestBase;
import cn.dkdoo.blackhorse_transactional.common.TestParse;
import cn.dkdoo.blackhorse_transactional.common.TestTraUser;
import cn.dkdoo.utils.common.ThreadLocalPool;
import cn.dkdoo.utils.config.DkdTransactionConfig;
import cn.dkdoo.utils.config.exception.DkdTransactionException;
import cn.dkdoo.utils.config.traNo.TraNoBuild;
import cn.dkdoo.utils.entity.BaseRequest;
import cn.dkdoo.utils.utils.DkdSpringUtils;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.util.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * @author nicky
 * @date 2021/7/21 下午2:21
 */
public class DkdAssert {
    private static final Logger logger = LoggerFactory.getLogger(DkdAssert.class);

    private String methodName;
    private String expectVal;
    private List<String> testVals;
    private BaseRequest request;


    public static void main(String[] args) {
        TestTraUser data = TestTraUser.getOne();
        //new BasicDBObject()

        TestParse testParse = new TestParse("aa");
        JSON.serialize(testParse);
    }

    public DkdAssert(String methodName) {
        this.methodName = methodName;
        this.request = TestBase.getOneRequestStatic();
        this.testVals = new ArrayList<>();
    }

    public DkdAssert setExpectVal(Object testRes) {
        this.expectVal = JSONObject.toJSONString(testRes);
        return this;
    }

    public DkdAssert setExpectValSelf(IDoTest iDoTest) {
        Object testRes = iDoTest.doTest();
        this.expectVal = JSONObject.toJSONString(testRes);
        return this;
    }

    public DkdAssert addTestVal(Object testRes) {
        this.testVals.add(JSONObject.toJSONString(testRes));
        return this;
    }

    public DkdAssert addTestVal(IDoTest iDoTest) {
        Object testRes = iDoTest.doTest();
        this.testVals.add(JSONObject.toJSONString(testRes));
        return this;
    }


    public DkdAssert startTra() {
        TraNoBuild.startTra(request);
        return this;
    }

    public DkdAssert before(IDoCommitTest iDoCommitTest) {
        iDoCommitTest.doBusiness();
        return this;
    }

    public DkdAssert after(IDoCommitTest iDoCommitTest) {
        iDoCommitTest.doBusiness();
        return this;
    }

    public DkdAssert checkCommitSuccess(IDoCommitSuccessTest iDoCommitTest) {
        if (!Boolean.TRUE.equals(iDoCommitTest.doBusiness())) {
            throw new DkdTransactionException("方法：{}，commit失败！", methodName);
        }
        return this;
    }

    public DkdAssert commit(IDoCommitTest iDoCommitTest) {
        iDoCommitTest.doBusiness();
        DkdSpringUtils.getBeanByClass(DkdTransactionConfig.class).commit();
        return this;
    }

    public DkdAssert rollback(IDoRollbackTest iDoRollbackTest) {
        iDoRollbackTest.doBusiness();
        return this;
    }

    public DkdAssert rollback() {
        DkdSpringUtils.getBeanByClass(DkdTransactionConfig.class).rollback(request.buildTraNo());
        return this;
    }

    public DkdAssert doCheck() {
        for (String testVal : testVals) {
            if (!testVal.equals(expectVal)) {
                throw new DkdTransactionException("方法：{}，期望结果：{}，测试结果：{}，不匹配！", methodName, expectVal, testVal);
            }
        }
        logger.info("方法：{}，测试通过！", methodName);
        //每一个测试完，需要重置ThreadLocal
        ThreadLocalPool.releaseToThread(ThreadLocalPool.TRA_NO_MANAGER, ThreadLocalPool.TRAINFO_MANAGER);
        return this;
    }
}